Ext.define('MyApp.controller.FeedController', {
    extend: 'Ext.app.Controller',

    refs: [
        {
            ref: 'feedPanel',
            selector: 'feedpanel'
        },
        {
            ref: 'feedInfo',
            selector: 'feedinfo'
        },
        {
            ref: 'feedPost',
            selector: '#feedpost'
        },
        {
            ref: 'feedWindow',
            selector: 'feedwindow'
        },
        {
            ref: 'feedUrl',
            selector: 'feedwindow #feed'
        },
        {
            ref: 'feedForm',
            selector: 'feedwindow #form'
        },
        {
            ref: 'feedPanelView',
            selector: 'feedpanel #dataview'
        },
        {
            ref: 'feedGridView',
            selector: 'feedgrid #view'
        }
    ],

    onDataviewSelectionChange: function(dataview, selections, options) {
        var removeButton = this.getFeedPanel().down('#remove');

        removeButton.setDisabled(!selections.length);

        if (selections.length > 0) {
            this.loadFeed(selections[0]);
        }
    },

    onGridpanelSelectionChange: function(tablepanel, selections, options) {
        if (selections.length > 0) {
            this.loadPost(selections[0]);
        }
    },

    onDataviewViewReady: function(abstractview, options) {
        abstractview.getSelectionModel().select(abstractview.store.first());
    },

    onOpenAddFeedWindow: function(button, e, options) {
        var win = Ext.create('widget.feedwindow');
        win.show();
    },

    onFeedWindowCancel: function(button, e, options) {
        this.getFeedWindow().destroy();
    },

    onAddFeed: function(button, e, options) {
        var url = this.getFeedUrl().getValue();
        this.getFeedForm().setLoading({
            msg: 'Validating feed...'
        });

        Ext.Ajax.request({
            url: 'feed-proxy.php',
            params: {
                feed: url
            },
            success: this.validateFeed,
            failure: this.markInvalid,
            scope: this
        });
    },

    onRemoveFeed: function(button, e, options) {
        var view = this.getFeedPanelView(),
            active = view.getSelectionModel().getSelection()[0];

        this.animateNode(view.getNode(active), 1, 0, {
            scope: this,
            afteranimate: function() {
                view.store.remove(active);
                view.getSelectionModel().select(view.store.first());
            }
        });


    },

    onSummaryToggle: function(button, pressed, options) {
        button.up('feedgrid').down('#view').getPlugin('preview').toggleExpanded(pressed);
    },

    onReadingPaneChange: function(cycle, item, options) {
        var east = cycle.up('feeddetail').down('#east'),
            south = cycle.up('feeddetail').down('#south'),
            display = cycle.up('feeddetail').down('feedpost');

        switch (item.text) {
            case 'Bottom':
            east.hide();
            south.show();
            south.add(display);
            break;
            case 'Right':
            south.hide();
            east.show();
            east.add(display);
            break;
            default:
            south.hide();
            east.hide();
            break;
        }
    },

    onOpenAll: function(button, e, options) {
        this.onTabOpen(null, Ext.getStore('FeedItemStore').getRange());
    },

    onDataviewItemDblClick: function(tablepanel, record, item, index, e, options) {
        this.onTabOpen(null, record);
    },

    onGotoPostClick: function(button, e, options) {
        var post = button.up('feedpost');

        window.open(post.active.get('link'));
    },

    onViewInTabClick: function(button, e, options) {
        var post = button.up('feedpost');

        this.onTabOpen(post, post.active);
    },

    loadFeed: function(feed) {
        var feedInfo = this.getFeedInfo(),
            active = feedInfo.items.first(),
            feedTitle = feed.get('title'),
            feedUrl = feed.get('url');

        if (!active) {
            feedInfo.add({
                xtype: 'feeddetail',
                title: feedTitle,
                url: feedUrl
            });
        } else {
            active.loadFeed(feedUrl);
            active.tab.setText(feedTitle);
        }

        feedInfo.setActiveTab(active);
    },

    loadPost: function(post) {
        var feedPost = this.getFeedPost();

        feedPost.active = post;
        feedPost.update(post.data);
    },

    markInvalid: function() {
        this.getFeedForm().setLoading(false);
        this.getFeedUrl().markInvalid('The URL specified is not a valid RSS2 feed.');
    },

    validateFeed: function(response) {
        this.getFeedForm().setLoading(false);

        var dq = Ext.DomQuery,
            url = this.getFeedUrl().getValue(),
            xml,
            channel,
            title,
            rec;

        try {
            xml = response.responseXML;
            channel = xml.getElementsByTagName('channel')[0];
            if (channel) {
                title = dq.selectValue('title', channel, url);

                rec = Ext.getStore('FeedStore').add({
                    url: url,
                    title: title
                })[0];
                this.animateNode(this.getFeedPanelView().getNode(rec), 0, 1);

                this.getFeedWindow().destroy();
                return;
            }
        } catch(e) {
        }
        this.markInvalid();
    },

    animateNode: function(el, start, end, listeners) {
        Ext.create('Ext.fx.Anim', {
            target: Ext.get(el),
            duration: 500,
            from: {
                opacity: start
            },
            to: {
                opacity: end
            },
            listeners: listeners
        });
    },

    onTabOpen: function(post, rec) {
        var feedInfo = this.getFeedInfo(),
            items = [],
            item;

        if (Ext.isArray(rec)) {
            Ext.each(rec, function(rec) {
                items.push({
                    inTab: true,
                    xtype: 'feedpost',
                    title: rec.get('title'),
                    closable: true,
                    data: rec.data,
                    active: rec
                });
            });
            feedInfo.add(items);
        } else {
            item = feedInfo.add({
                inTab: true,
                xtype: 'feedpost',
                title: rec.get('title'),
                closable: true,
                data: rec.data,
                active: rec
            });
            feedInfo.setActiveTab(item);
        }
    },

    init: function(application) {
        this.control({
            "#feedpanel #dataview": {
                selectionchange: this.onDataviewSelectionChange
            },
            "#feedgrid": {
                selectionchange: this.onGridpanelSelectionChange,
                itemdblclick: this.onDataviewItemDblClick
            },
            "#feedpanel dataview": {
                viewready: this.onDataviewViewReady
            },
            "#feedpanel #add": {
                click: this.onOpenAddFeedWindow
            },
            "feedwindow #cancel": {
                click: this.onFeedWindowCancel
            },
            "feedwindow #add": {
                click: this.onAddFeed
            },
            "feedpanel #remove": {
                click: this.onRemoveFeed
            },
            "feedgrid #summary": {
                toggle: this.onSummaryToggle
            },
            "feedgrid #readingpane": {
                change: this.onReadingPaneChange
            },
            "feedgrid #openall": {
                click: this.onOpenAll
            },
            "feedpost #gotopost": {
                click: this.onGotoPostClick
            },
            "feedpost #viewintab": {
                click: this.onViewInTabClick
            }
        });
        Ext.getStore('FeedItemStore').on('load', function() {
            this.getFeedGridView().getSelectionModel().select(0);
        }, this);
    },

    onControllerSelectionChangeStub: function() {

    },

    onControllerClickStub: function() {

    }

});
